package com.cloudptt.wp.ui.address.map.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.Marker;
import org.osmdroid.views.overlay.Marker.OnMarkerClickListener;
import org.osmdroid.views.overlay.Marker.OnMarkerDragListener;
import org.osmdroid.views.overlay.infowindow.InfoWindow;

import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.wp.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.location.Location;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MarkerTools {

	private Context context;
	private PopupWindow popupWindow;
	private Activity activity;
	private GeoPoint mArmyMarkPoint;
	private ImageView myMonitor_me;
	private ImageView myMonitor_friend;
	private ImageView myMonitor_enemy;
	private TextView mLongitude_Mark;
	private TextView mLatitude_Mark;
	private TextView mLocation_Distance;

	private MapView mMapView;

	public List<Marker> mArmyMarkers = new ArrayList<Marker>();
	public ArrayList<Marker> mMarkerReceiveList = new ArrayList<Marker>();
	public HashMap<Marker, View> roundMenuMap = new HashMap<Marker, View>();
	public HashMap<RoundMenuView.RoundMenu, Marker> roundMarkerMap = new HashMap<RoundMenuView.RoundMenu, Marker>();
	public ArrayList<Marker> sendedMarker = new ArrayList<Marker>();
	public RoundMenuView roundMenuView;

	public MarkerTools(Activity activity) {
		// TODO Auto-generated constructor stub
		this.activity = activity;
		context = activity.getApplicationContext();
	}


	public void initMap(MapView mapview){
		mMapView = mapview;
	}

	//init popupwindow of army marker
	public void initPopupWindow(){
		View contentView = LayoutInflater.from(context)
				.inflate(R.layout.armymarker_popwindow, null);
		WindowManager wm = activity.getWindowManager();
		int width = wm.getDefaultDisplay().getWidth();
		int height = wm.getDefaultDisplay().getHeight();
		popupWindow = new PopupWindow(contentView, width, height / 2);
		popupWindow.setFocusable(true);
		popupWindow.setOutsideTouchable(false);

		myMonitor_me = (ImageView) contentView.findViewById(R.id.monitor_me);
		myMonitor_friend = (ImageView) contentView.findViewById(R.id.monitor_friend);
		myMonitor_enemy = (ImageView) contentView.findViewById(R.id.monitor_enemy);
		mLongitude_Mark = (TextView) contentView.findViewById(R.id.longitude_mark);
		mLatitude_Mark = (TextView) contentView.findViewById(R.id.latitude_mark);
		mLocation_Distance = (TextView) contentView.findViewById(R.id.location);

		myMonitor_me.setOnClickListener(mArmyMarkClick);
		myMonitor_friend.setOnClickListener(mArmyMarkClick);
		myMonitor_enemy.setOnClickListener(mArmyMarkClick);
	}

	private OnClickListener mArmyMarkClick = new OnClickListener() {
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.monitor_me:
				addArmyMarker(R.drawable.army_mark_me, true);
				break;
			case R.id.monitor_friend:
				addArmyMarker(R.drawable.army_mark_friend, true);
				break;
			case R.id.monitor_enemy:
				addArmyMarker(R.drawable.army_mark_enemy, true);
				break;
			}
		}
	};


	public void showPopupWindow(GeoPoint marker_p, GeoPoint current_loc){
		
		if(mMapView == null){
			return;
		}
		
		popupWindow.showAtLocation(activity.findViewById(R.id.map_layout), Gravity.BOTTOM, 0, 0);
		mArmyMarkPoint = marker_p;
		if (marker_p == null) {
			mLongitude_Mark.setText("--");
			mLatitude_Mark.setText("--");
			mLocation_Distance.setText("--");
		} else {
			mLongitude_Mark.setText((double) Math.round(mArmyMarkPoint.getLongitude() * 100) / 100 + "");
			mLatitude_Mark.setText((double) Math.round(mArmyMarkPoint.getLatitude() * 100) / 100 + "");
			float[] results = new float[1];
			Location.distanceBetween(current_loc.getLatitude(), current_loc.getLongitude(),
					mArmyMarkPoint.getLatitude(), mArmyMarkPoint.getLongitude(), results);
			mLocation_Distance.setText((double) Math.round(results[0] * 100) / 100 + "m");
		}
	}

	public Marker addArmyMarker(int markResource, boolean addOrReceive) {
		Marker marker = new Marker(mMapView);
		marker.setPosition(mArmyMarkPoint);
		Drawable drawable = context.getResources().getDrawable(markResource);
		marker.setIcon(drawable);
		marker.setDraggable(true);
		
		initMarkerInfo(marker);

		popupWindow.dismiss();

		marker.setOnMarkerClickListener(mShowMenuClick);
		marker.setOnMarkerDragListener(dListener);
		if (mMapView != null) {
			mMapView.getOverlayManager().add(marker);
			mMapView.invalidate();
		}
		mArmyMarkers.add(marker);
		if(addOrReceive == false){
			mMarkerReceiveList.add(marker);
		}
		return marker;

	}
	
	private void initMarkerInfo(Marker marker){
				
		InfoWindow infowindows = new InfoWindow(R.layout.marker_info_window, mMapView) {
			@Override
			public void onOpen(Object object) {
				// TODO Auto-generated method stub
				
				if(object != null && object instanceof GeoPoint){
					GeoPoint point = (GeoPoint)object;
					showLocationInfo(getView().findViewById(R.id.marker_title), point);
				}
			}

			@Override
			public void onClose() {
				// TODO Auto-generated method stub
				
			}
			
			private void showLocationInfo(View view, GeoPoint point) {
				// TODO Auto-generated method stub

				if(view != null && view instanceof TextView){
					((TextView)view).setText((double) Math.round(point.getLongitude() * 100) / 100 + ","
							+ (double) Math.round(point.getLatitude() * 100) / 100);
				}
			}
		};
		marker.setInfoWindow(infowindows);
		infowindows.open(null, null, 0, 0);
	}

	OnMarkerDragListener dListener = new OnMarkerDragListener(){

		@Override
		public void onMarkerDrag(Marker marker) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onMarkerDragEnd(Marker marker) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onMarkerDragStart(Marker marker) {
			// TODO Auto-generated method stub
			marker.closeInfoWindow();
			ArrayList<RoundMenuView.RoundMenu> containKeys = new ArrayList<RoundMenuView.RoundMenu>();
			if (roundMenuMap.size() > 0) {
				mMapView.removeView(roundMenuMap.get(marker));// remove circle button
			}
			roundMenuMap.remove(marker);
			for (RoundMenuView.RoundMenu key : roundMarkerMap.keySet()) {
				if (roundMarkerMap.get(key).equals(marker)) {
					containKeys.add(key);
				}
			}
			for (int i = 0; i < containKeys.size(); i++) {
				roundMarkerMap.remove(containKeys.get(i));
			}
		}

	};
	// show circle button when click marker
	Marker.OnMarkerClickListener mShowMenuClick = new OnMarkerClickListener() {

		@Override
		public boolean onMarkerClick(Marker marker, MapView mapView) {
			// click marker show menu or hide menu
			// get marker's location	
			if (roundMenuMap != null && !roundMenuMap.containsKey(marker)) {
				MarkerRoundMenu markinfowindows = new MarkerRoundMenu(R.layout.marker_round_layout, mapView);
				markinfowindows.open(this, marker, marker.getPosition(), 0, 0);
				roundMenuMap.put(marker, markinfowindows.getLayout());
				roundMenuView = markinfowindows.getRoundMenuView();
				roundMenuView.setCoreMenu(2, 
						(double) 0.2, 
						context.getResources().getColor(R.color.transparent),
						context.getResources().getColor(R.color.transparent), 
						context.getResources().getColor(R.color.transparent));
				showOtherMenu(marker);
				roundMenuView.invalidate(); // draw circle

			} else if (roundMenuMap != null && roundMenuMap.containsKey(marker)) {
				ArrayList<RoundMenuView.RoundMenu> containKeys = new ArrayList<RoundMenuView.RoundMenu>();
				if (roundMenuMap.size() > 0) {
					mMapView.removeView(roundMenuMap.get(marker));
				}
				roundMenuMap.remove(marker);
				for (RoundMenuView.RoundMenu key : roundMarkerMap.keySet()) {
					if (roundMarkerMap.get(key).equals(marker)) {
						containKeys.add(key);
					}
				}
				for (int i = 0; i < containKeys.size(); i++) {
					roundMarkerMap.remove(containKeys.get(i));
				}
			}
			roundMenuView.invalidate();
			return false;
		}
	};

	/* show other button around */
	public void showOtherMenu(Marker marker) {
		
		final RoundMenuView.RoundMenu roundMenu = new RoundMenuView.RoundMenu();
		roundMarkerMap.put(roundMenu, marker);
		roundMenu.strokeColor = context.getResources().getColor(R.color.color_gray);
		if(sendedMarker.contains(roundMarkerMap.get(roundMenu))){
			roundMenu.icon = drawable2Bitmap(context.getResources().getDrawable(R.drawable.more_info_select));
		} else {
			roundMenu.icon = drawable2Bitmap(context.getResources().getDrawable(R.drawable.more_info_normal));
		}
		roundMenu.onClickListener = new OnClickListener() {
			public void onClick(View v) {
				if(sendedMarker.contains(roundMarkerMap.get(roundMenu))){
					//Can't send twice
					Log.d("lsls", "Can't send twice");
				} else{
					sendedMarker.add(roundMarkerMap.get(roundMenu));
					Log.d("lsls", "send success");
				}

				CommDlg.show(context, "Click 1");
			}
		};
		roundMenuView.addRoundMenu(roundMenu);

		final RoundMenuView.RoundMenu roundMenu2 = new RoundMenuView.RoundMenu();
		roundMenu2.strokeColor = context.getResources().getColor(R.color.color_gray);
		roundMenu2.icon = drawable2Bitmap(context.getResources().getDrawable(R.drawable.more_info_normal));
		roundMarkerMap.put(roundMenu2, marker);
		roundMenu2.onClickListener = new OnClickListener() {
			public void onClick(View v) {
				if (roundMenu2.icon == drawable2Bitmap(context.getResources().getDrawable(R.drawable.more_info_select))) {
					// show lat and lng
					Marker marker = roundMarkerMap.get(roundMenu2);
					marker.getInfoWindow().open(marker.getPosition(), marker.getPosition(), 0, 0);
					//Log.d("lq", "marker.getPosition() = "+marker.getPosition().getLatitude()+", "+marker.getPosition().getLongitude());
				} else if (roundMenu2.icon == drawable2Bitmap(context.getResources().getDrawable(R.drawable.more_info_normal))) {
					// cancel show
					roundMarkerMap.get(roundMenu2).getInfoWindow().open(null, null, 0, 0);
					//roundMarkerMap.get(roundMenu2).getInfoWindow().close();
				}
				CommDlg.show(context, "Click 2");
			}
		};
		roundMenuView.addRoundMenu(roundMenu2);

		final RoundMenuView.RoundMenu roundMenu3 = new RoundMenuView.RoundMenu();
		roundMenu3.strokeColor = context.getResources().getColor(R.color.color_gray);
		roundMenu3.icon = null;
		//	roundMenu3.icon = drawable2Bitmap(getActivity().getApplicationContext(),
		//context.getResources().getDrawable(R.drawable.video_call_normal));
		roundMarkerMap.put(roundMenu3, marker);
		roundMenu3.onClickListener = new OnClickListener() {
			public void onClick(View v) {

				CommDlg.show(context, "Click 3");
			}
		};
		roundMenuView.addRoundMenu(roundMenu3);

		final RoundMenuView.RoundMenu roundMenu4 = new RoundMenuView.RoundMenu();
		roundMenu4.strokeColor = context.getResources().getColor(R.color.color_gray);
		roundMenu4.icon = drawable2Bitmap(context.getResources().getDrawable(R.drawable.button_delete_normal));
		roundMarkerMap.put(roundMenu4, marker);
		roundMenu4.onClickListener = new OnClickListener() {
			public void onClick(View v) {
				if(!mMarkerReceiveList.contains(roundMarkerMap.get(roundMenu4))){
					ArrayList<RoundMenuView.RoundMenu> containKeys = new ArrayList<RoundMenuView.RoundMenu>();
					Marker marker = roundMarkerMap.get(roundMenu4);
					deleteArmyMarkerImage(roundMarkerMap.get(roundMenu4), mMapView);
					mMapView.removeView(roundMenuMap.get(roundMarkerMap.get(roundMenu4)));// remove circle button
					for (RoundMenuView.RoundMenu key : roundMarkerMap.keySet()) {
						if (roundMarkerMap.get(key).equals(marker)) {
							containKeys.add(key);
						}
					}
					for (int i = 0; i < containKeys.size(); i++) {
						roundMarkerMap.remove(containKeys.get(i));
					}
				}
				CommDlg.show(context, "Click 4");
			}
		};
		roundMenuView.addRoundMenu(roundMenu4);
	}

	public void deleteArmyMarkerImage(Marker marker, MapView mapView) {
		marker.closeInfoWindow();
		if(mArmyMarkers.contains(marker)){
			mArmyMarkers.remove(marker);
		}
		if(mMarkerReceiveList.contains(marker)){
			mMarkerReceiveList.remove(marker); 
		}
		//remove marker in database, and notify server
		marker.remove(mMapView);
	}

	public Bitmap drawable2Bitmap(Drawable drawable) {
		if (drawable instanceof BitmapDrawable) {
			return ((BitmapDrawable) drawable).getBitmap();
		} else if (drawable instanceof NinePatchDrawable) {
			Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
					drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
			Canvas canvas = new Canvas(bitmap);
			drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
			drawable.draw(canvas);
			return bitmap;
		} else {
			return null;
		}
	}

}
